package list;

/**
 * @since   13/08/1992
 * @author Ben
 * @param <E> Tipo de objetos que utiliza esta clase
 * Basado en código de Java Structures de Duan y Baily
 */
public class ListaCircular<E> extends AbstractList<E> 
{
    protected Nodo<E> tail; 
    protected int count;

    public ListaCircular()
    // pre: constructs a new circular list
    // post: No hay.
    {
        tail = null;
        count = 0;
    }

    @Override
    public void addFirst(E value)
    // pre: value non-null
    // post: adds element to head of list
    {
        Nodo<E> temp = new Nodo<>(value);
        if (tail == null) { // first value added
            tail = temp;
            tail.setNext(tail);
        } else { // element exists in list
            temp.setNext(tail.next());
            tail.setNext(temp);
        }
        count++;
    }


    public void addLast(E value)
    // pre: value non-null
    // post: adds element to tail of list
    {
        // new entry:
        addFirst(value);
        tail = tail.next();
    }


    // lo dificil es quitar el elemento de la cola

    public E removeLast()
    // pre: !isEmpty()
    // post: returns and removes value from tail of list
    {
        Nodo<E> finger = tail;
        while (finger.next() != tail) {
            finger = finger.next();
        }
        // finger now points to second-to-last value
        Nodo<E> temp = tail;
        if (finger == tail)
        {
            tail = null;
        } else {
            finger.setNext(tail.next());
            tail = finger;
        }
        count--;
        return temp.value();
    }


    @Override
    // pre: No hay.
    // post: Se devuelve el tamaño de la lista.
    public int size() {
        return count;
    }

    @Override
    // pre: La lista no está vacía.
    // post: Se devuelve el primer elemento de la lista.
    public E getFirst() {
        return tail.nextElement.value();
    }

    @Override
    // pre: La lista no está vacía.
    // post: Se devuelve el primer elemento de la lista y se retira de esta.
    public E removeFirst() {
        Nodo<E> temp = tail.next();
        if (tail == temp) { // first value added
            tail = null;
        } else { // element exists in list
            tail.setNext(temp.next());;
        }
        count--;
        return temp.value();
    }
}

